package edu.usm.roberge.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;

import edu.usm.roberge.server.usga.UsgaCourseListRequest;

/**
 * Wrapper class for HttpURLConnection
 * This class is a convenience class to make Http requests easier on the client
 * 
 * @author Dave Roberge
 */
public class HttpRequest {

	private final String url;
	private final Map<String, String> params;
	private boolean posting;
	private final Logger logger = Logger.getLogger(HttpRequest.class.getName());
	private Map<String, List<String>> headers;
	private Map<String, String> requestHeaders = new HashMap<String, String>();

	public HttpRequest(String url) {
		this.url = url;
		params = new HashMap<String, String>();
	}
	
	public HttpRequest addParameter(String paramName, String paramValue) {
		params.put(paramName, paramValue);
		return this;
	}
	
	public HttpRequest addRequestHeader(String headerName, String value) {
		requestHeaders.put(headerName, value);
		return this;
	}
	
	public HttpRequest setPostRequest() {
		posting = true;
		return this;
	}
	
	public HttpRequest setGetRequest() {
		posting = false;
		return this;
	}
	
	public String makeRequest() {
		try {
			URL targetUrl = new URL(url);
			HttpURLConnection conn = (HttpURLConnection)targetUrl.openConnection();
			addRequestHeaders(conn);
			if (posting) {
				addPostParameters(conn);
			}
			return readResponse(conn);
		} catch (MalformedURLException e) {

		} catch (IOException e) {

		}
		
		return "";
	}

	private void addRequestHeaders(HttpURLConnection conn) {
		for(Entry<String, String> header : requestHeaders.entrySet()) {
			conn.addRequestProperty(header.getKey(), header.getValue());
		}
	}

	private void addPostParameters(HttpURLConnection conn) {
		conn.setDoOutput(true);
		conn.addRequestProperty("Content-type", "application/x-www-form-urlencoded");
		try {
			OutputStream os = conn.getOutputStream();
			StringBuffer buf = new StringBuffer();
			for(Entry<String, String> param : params.entrySet()) {
				String p = param.getKey() + "=" + URLEncoder.encode(param.getValue(), "utf8");
				if (buf.length() > 0) {
					buf.append("&");
				}
				buf.append(p);
			}
			logger.info("Full request body: " + buf.toString());
			os.write(buf.toString().getBytes());
		} catch (IOException e) {
			logger.severe("Failed to write post request body: " + e.getMessage());
		}
	}


	private String readResponse(HttpURLConnection conn) {
		try {
			conn.connect();
			headers = conn.getHeaderFields();
			
			BufferedReader is = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf8"));
			StringBuffer response = new StringBuffer();
			String line = is.readLine();
			while(line != null) {
				if (!line.trim().isEmpty()) {
					response.append(line);
				}
				line = is.readLine();
			}
			return response.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";
	}

	public List<String> getHeader(String header) {
		return headers.get(header);
	}
}
